<template>
    <div class="flex-center gap-2">
        <input v-for="(item, index) in codes"
               :key="index"
               :ref="(el) => (inputRefs[index] = el)"
               v-model="codes[index]"
               type="text"
               maxlength="1"
               @input="handleInput(index, $event)"
               @keydown.delete="handleDelete(index, $event)"
               @focus="handleFocus"
               @paste="handlePaste"
               class="w-[50px] h-[50px] text-center rounded-md text-2xl"
               :class="{ 'has-value': codes[index] }" />
    </div>
</template>

<script setup lang="ts">
import { ref, watch, nextTick } from 'vue';

const props = defineProps({
    length: {
        type: Number,
        default: 4
    }
});

const value = defineModel<string>();

const emit = defineEmits(['complete']);

const codes = ref(Array(props.length).fill(''));
const inputRefs = ref<any[]>([]);

// 处理输入
const handleInput = (index: number, event: any) => {
    const value = event.target.value;

    // 只允许数字输入
    if (!/^\d*$/.test(value)) {
        codes.value[index] = '';
        return;
    }

    // 自动跳转到下一个输入框
    if (value && index < props.length - 1) {
        nextTick(() => {
            inputRefs.value[index + 1]?.focus();
        });
    }

    // 检查是否全部填写完成
    checkCompletion();
};

// 处理删除键
const handleDelete = (index: number, event: any) => {
    if (!codes.value[index] && index > 0) {
        // 当前为空且不是第一个输入框，退格时聚焦到前一个
        event.preventDefault();
        inputRefs.value[index - 1]?.focus();
    }
};

// 处理聚焦事件
const handleFocus = (event) => {
    // 选中文本方便重新输入
    event.target.select();
};

// 处理粘贴
const handlePaste = (event) => {
    event.preventDefault();
    const pasteData = event.clipboardData?.getData('text/plain').trim();

    if (pasteData && /^\d+$/.test(pasteData)) {
        const pasteDigits = pasteData.split('').slice(0, props.length);
        pasteDigits.forEach((digit, i) => {
            if (i < props.length) {
                codes.value[i] = digit;
            }
        });

        // 聚焦到最后一个有值的输入框
        const lastFilledIndex = Math.min(pasteDigits.length - 1, props.length - 1);
        nextTick(() => {
            inputRefs.value[lastFilledIndex]?.focus();
        });

        checkCompletion();
    }
};

// 检查是否全部填写完成
const checkCompletion = () => {
    value.value = codes.value.join('');
    if (codes.value.every(code => code !== '')) {
        emit('complete', codes.value.join(''));
    }
};

// 暴露方法给父组件
defineExpose({
    clear: () => {
        codes.value = Array(props.length).fill('');
        nextTick(() => {
            inputRefs.value[0]?.focus();
        });
    },
    getCode: () => codes.value.join('')
});
</script>

<style scoped>
.verification-code {
    display: flex;
    justify-content: center;
    gap: 10px;
}

.verification-code input {
    width: 50px;
    height: 60px;
    text-align: center;
    font-size: 24px;
    border: 1px solid #ddd;
    border-radius: 4px;
    outline: none;
    transition: all 0.3s;
}

.verification-code input:focus {
    border-color: #409eff;
    box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2);
}

.verification-code input.has-value {
    border-color: #67c23a;
}
</style>